﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using HigLabo.Net;

namespace HigLabo.WindowsAzure.RestService.SqlAzureManagement
{
    /// <summary>
    /// http://msdn.microsoft.com/ja-jp/library/windowsazure/gg715283
    /// </summary>
    public class SqlAzureManagementServiceClient
    {
        /// <summary>
        /// サブスクリプションID
        /// </summary>
        public String SubscriptionID { get; private set; }
        /// <summary>
        /// 証明書
        /// </summary>
        public X509Certificate2 Certificate { get; private set; }
        // <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="subscriptionID"></param>
        /// <param name="certThumbprint"></param>
        public SqlAzureManagementServiceClient(String subscriptionID, String certThumbprint)
        {
            if (String.IsNullOrEmpty(certThumbprint))
            {
                throw new ArgumentException("certThumbprint");
            }
            Initialize(subscriptionID, GetCertificate(certThumbprint));
        }
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="subscriptionID"></param>
        /// <param name="certificate"></param>
        public SqlAzureManagementServiceClient(String subscriptionID, X509Certificate2 certificate)
        {
            Initialize(subscriptionID, certificate);
        }
        /// <summary>
        /// 初期化メソッド
        /// </summary>
        /// <param name="subscriptionID"></param>
        /// <param name="certificate"></param>
        private void Initialize(String subscriptionID, X509Certificate2 certificate)
        {
            if (String.IsNullOrEmpty(subscriptionID))
            {
                throw new ArgumentException("subscriptionID");
            }
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }
            SubscriptionID = subscriptionID;
            Certificate = certificate;
        }
        /// <summary>
        /// 証明書の取得
        /// </summary>
        /// <param name="certThumbprint"></param>
        /// <returns></returns>
        public static X509Certificate2 GetCertificate(String certThumbprint)
        {
            var certCollection = GetCertificateCollection();
            var cert = certCollection.Find(X509FindType.FindByThumbprint, certThumbprint, false);
            // Check to see if our certificate was added to the collection. If no, throw an error, if yes, create a certificate using it.
            if (certCollection.Count == 0)
            {
                throw new ArgumentException("No certificate found containing thumbprint " + certThumbprint, "certThumbprint");
            }
            // Create an X509Certificate2 object using our matching certificate.
            return cert[0];
        }
        /// <summary>
        /// 証明書リストの取得
        /// </summary>
        /// <returns></returns>
        public static X509Certificate2Collection GetCertificateCollection()
        {
            // Create a reference to the My certificate store.
            X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            // Try to open the store.
            certStore.Open(OpenFlags.ReadOnly);
            // Find the certificate that matches the thumbprint.
            X509Certificate2Collection certCollection = certStore.Certificates;
            certStore.Close();
            return certCollection;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="command"></param>
        /// <returns></returns>
        public T Execute<T>(SqlAzureManagementServiceCommand<T> command) where T : SqlAzureManagementServiceResult, new()
        {
            // Build a URI for https://management.database.windows.net:8443/{SubscriptionID}/servers
            String requestUri = command.GetRequestUri();
            if (String.IsNullOrEmpty(requestUri))
                requestUri = String.Format("https://management.database.windows.net:8443/{0}/servers", this.SubscriptionID);
            else
                requestUri = String.Format("https://management.database.windows.net:8443/{0}/servers/{1}", this.SubscriptionID, requestUri);
            HttpClient cl = new HttpClient();
            cl.ClientCertificates.Add(this.Certificate);

            var cm = new HttpRequestCommand(requestUri, command.MethodName);
            if (string.IsNullOrEmpty(command.ContentType) == false)
            {
                cm.ContentType = command.ContentType;
            }
            cm.Headers["x-ms-version"] = "1.0";
            var hd = command.GetRequestHeaders();
            if (hd != null)
            {
                foreach (var item in hd)
                {
                    cm.Headers[item.Key] = item.Value;
                }
            }
            var body = command.GetRequestBodyStream();
            HttpResponse response;
            if (body == null)
            {
                response = cl.GetResponse(cm);
            }
            else
            {
                cm.SetBodyStream(body);
                response = cl.GetResponse(cm);
            }
            var res = new T();
            res.SetResponseData(response);
            return res;
        }
        #region DatabaseServerコマンド
        
        public GetServersResult UpdateDeploymentStatus(GetServersCommand command)
        {
            return Execute(command);
        }

        #endregion
    }
}
